package com.infocollect.common.utils.sign;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.List;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.misc.BASE64Decoder;

public class AES {

	//密钥 (需要前端和后端保持一致)
	private static final String KEY = "E54FGA6DS5DFG8F4";
	//算法
	private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

	private static String sKey="C724DA350F57BD5DB2CEF197047605AD";
	private volatile static boolean isInit = false;
	public static byte[] encrypt(String content, byte[] enCodeFormat) {
		try {
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
			byte[] byteContent = content.getBytes("utf-8");
			cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(byteContent);
			return result; // 加密
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 *
	 * @param content
	 *            待解密内容
	 * @param
	 *
	 * @return
	 */
	public static byte[] decrypt(byte[] content,byte[] enCodeFormat) {
		try {

			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(content);
			return result; // 加密
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将二进制转换成16进制
	 *
	 * @param buf
	 * @return
	 */
	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * 将16进制转换为二进制
	 *
	 * @param hexStr
	 * @return
	 */
	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
					16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}
	public static String decode(String code){
		String result = decode(code, sKey);
		return result;
	}
	public static String decode(String code,byte[] key){
		byte[] decryptFrom = parseHexStr2Byte(code);
		byte[] decryptResult = decrypt(decryptFrom,key);
		return new String(decryptResult);
	}
	public static String decode(String code,String key){
		byte[] decryptFrom = parseHexStr2Byte(code);
		byte[] decryptResult = decrypt(decryptFrom,parseHexStr2Byte(key));
		try {
			return new String(decryptResult,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	public static String encode(String content){
		return encode(content,sKey);
	}
	public static String encode(String content,byte[] key){
		byte[] encryptResult = encrypt(content, key);
		String encryptResultStr = parseByte2HexStr(encryptResult);
		return encryptResultStr;
	}
	public static String encode(String content,String keyString){
		byte[] encryptResult = encrypt(content, parseHexStr2Byte(keyString));
		String encryptResultStr = parseByte2HexStr(encryptResult);
		return encryptResultStr;
	}

	public static String makeKey(String password) throws NoSuchAlgorithmException{
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128, new SecureRandom(password.getBytes()));
		SecretKey secretKey = kgen.generateKey();
		byte[] enCodeFormat = secretKey.getEncoded();
		String encryptResultStr = parseByte2HexStr(enCodeFormat);
		return encryptResultStr;
	}


//	public static void main(String[] args) throws Exception {
//		String content = "18180818561,QWEasd123";
//		String content = "6839";
//		System.out.println("加密前：" + content);
//		System.out.println("加密密钥和解密密钥：E54FGA6DS5DFG8F4");
//		String cc = aesEncrypt(content, "E54FGA6DS5DFG8F4");
//		System.out.println("加密后：" + cc);
//		String dd = aesDecrypt("NcMyPTWB3bCsVxlKQ5jUvmtu2nrbjq+L4WtEt538Uxs=", "E54FGA6DS5DFG8F4");
//		System.out.println("解密后：" + dd);
//		 yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
//		String endpoint = "oss-cn-deqing-zjzfy01-d02-a.cloud-inner.zj.gov.cn";
////// 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
//		String accessKeyId = "P6UERw0yimfR0WEF";
//		String accessKeySecret = "HASAIm81sV9fAUUZ9OkO3Kp8t4KqzZ";
//
//
//// 创建ClientConfiguration。ClientConfiguration是OSSClient的配置类，可配置代理、连接超时、最大连接数等参数。
//		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,
//				accessKeySecret);
//		//OSSObject ossObject =ossClient.getObject("syf-bucket", "20220704/02e4f733a9e94a0bb547add7bd8122851.png");
//		//InputStream inputStream = ossObject.getObjectContent();
//		ObjectListing objectListing = ossClient.listObjects("xcjcgypt-oss", "");
//		List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
//		for (OSSObjectSummary s : sums) {
//			System.out.println("\t" + s.getKey());
//		}


//	}
	/**
	 * AES加密字符串
	 *
	 * @param content
	 *            需要被加密的字符串
	 *            加密需要的密码
	 * @return 密文
	 */
	public static String encrypt(String content) {
		try {
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			random.setSeed(sKey.getBytes());
			KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
			kgen.init(128, random);// 利用用户密码作为随机数初始化出
			// 128位的key生产者
			//加密没关系，SecureRandom是生成安全随机数序列，password.getBytes()是种子，只要种子相同，序列就一样，所以解密只要有password就行

			SecretKey secretKey = kgen.generateKey();// 根据用户密码，生成一个密钥

			byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥，如果此密钥不支持编码，则返回
			// null。

			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥

			Cipher cipher = Cipher.getInstance("AES");// 创建密码器

			byte[] byteContent = content.getBytes("utf-8");

			cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器

			byte[] result = cipher.doFinal(byteContent);// 加密

			return parseByte2HexStr(result);

		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 解密AES加密过的字符串
	 *
	 * @param content
	 *            AES加密过过的内容
	 * @return 明文
	 */
	public static String decrypt(String content) {
		try {
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			random.setSeed(sKey.getBytes());
			byte[] hexStrResult =parseHexStr2Byte(content);
			KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
			kgen.init(128, random);// 利用用户密码作为随机数初始化出
			SecretKey secretKey = kgen.generateKey();// 根据用户密码，生成一个密钥
			byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
			Cipher cipher = Cipher.getInstance("AES");// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器
			byte[] result = cipher.doFinal(hexStrResult);
			return new String(result); // 明文

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String decodeData(String encodingAesKey,String data,String iv) throws Exception {
		byte[] aesKey = Base64.decodeBase64(encodingAesKey);
		byte[] ivByte = Base64.decodeBase64(iv);
		byte[] content = Base64.decodeBase64(data);
		if(!isInit){
			Security.addProvider(new BouncyCastleProvider());
			isInit=!isInit;
		}
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
		Key sKeySpec = new SecretKeySpec(aesKey, "AES");
		cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
		byte[]  original = cipher.doFinal(content);
		return new String(original,"UTF-8");
	}
	private static AlgorithmParameters generateIV(byte[] iv) throws Exception {
		AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
		params.init(new IvParameterSpec(iv));
		return params;
	}

	/**
	 * true相等 false不相等
	 * @param password  加密
	 * @param password1  明文
	 * @return
	 */
	public static boolean passwordVerif(String password,String password1) {
		password=decrypt(password);
		if(StringUtils.isEmpty(password)) {
			return false;
		}
		if(password.equals(password1)) {
			return true;
		}
		return false;
	}





	/**
	 * aes解密
	 * @param encrypt   内容
	 * @return
	 * @throws Exception
	 */
	public static String aesDecrypt(String encrypt) {
		try {
			return aesDecrypt(encrypt, KEY);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	/**
	 * aes加密
	 * @param content
	 * @return
	 * @throws Exception
	 */
	public static String aesEncrypt(String content) {
		try {
			return aesEncrypt(content, KEY);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	/**
	 * 将byte[]转为各种进制的字符串
	 * @param bytes byte[]
	 * @param radix 可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
	 * @return 转换后的字符串
	 */
	public static String binary(byte[] bytes, int radix){
		return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
	}

	/**
	 * base 64 encode
	 * @param bytes 待编码的byte[]
	 * @return 编码后的base 64 code
	 */
	public static String base64Encode(byte[] bytes){
		return Base64.encodeBase64String(bytes);
	}

	/**
	 * base 64 decode
	 * @param base64Code 待解码的base 64 code
	 * @return 解码后的byte[]
	 * @throws Exception
	 */
	public static byte[] base64Decode(String base64Code) throws Exception{
		return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
	}


	/**
	 * AES加密
	 * @param content 待加密的内容
	 * @param encryptKey 加密密钥
	 * @return 加密后的byte[]
	 * @throws Exception
	 */
	public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(1, new SecretKeySpec(encryptKey.getBytes(), "AES"));
		return cipher.doFinal(content.getBytes("utf-8"));
	}


	/**
	 * AES加密为base 64 code
	 * @param content 待加密的内容
	 * @param encryptKey 加密密钥
	 * @return 加密后的base 64 code
	 * @throws Exception
	 */
	public static String aesEncrypt(String content, String encryptKey) throws Exception {
		return base64Encode(aesEncryptToBytes(content, encryptKey));
	}

	/**
	 * AES解密
	 * @param encryptBytes 待解密的byte[]
	 * @param decryptKey 解密密钥
	 * @return 解密后的String
	 * @throws Exception
	 */
	public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);

		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
		byte[] decryptBytes = cipher.doFinal(encryptBytes);
		return new String(decryptBytes);
	}


	/**
	 * 将base 64 code AES解密
	 * @param encryptStr 待解密的base 64 code
	 * @param decryptKey 解密密钥
	 * @return 解密后的string
	 * @throws Exception
	 */
	public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
		return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
	}





}
